<template>
  <el-dialog
    :showClose="getProps.showClose"
    :width="getProps.width"
    :draggable="getProps.draggable"
    :fullscreen="getFullscreen"
    v-bind="attrs"
    v-model="isModal"
    @close="onCloseModal"
  >
    <template #header>
      <div class="dialog-header">
        <div class="dialog-header-title">{{ getProps.title }}</div>
        <div class="dialog-header-action">
          <el-tooltip content="还原" placement="bottom" v-if="fullscreen">
            <el-link :underline="false" class="mr-4"
              ><el-icon class="el-input__icon" :size="18">
                <FullscreenExitOutlined role="full" @click="handleFullScreen" /> </el-icon
            ></el-link>
            >
          </el-tooltip>
          <el-tooltip v-else content="最大化" placement="bottom">
            <el-link :underline="false" class="mr-4"
              ><el-icon class="el-input__icon" :size="18"
                ><FullscreenOutlined role="close" @click="handleFullScreen" /></el-icon
            ></el-link>
          </el-tooltip>
          <el-tooltip content="关闭" placement="bottom">
            <el-link :underline="false" @click="onCloseModal"
              ><el-icon class="el-input__icon" :size="18"><CloseOutlined /></el-icon
            ></el-link>
          </el-tooltip>
        </div>
      </div>
    </template>
    <template #default>
      <slot name="default"></slot>
    </template>
    <template v-if="!getProps.hideFooter && !$slots.footer" #footer>
      <el-space>
        <slot name="prefixFooter"></slot>
        <el-button @click="closeModal" v-bind="getProps.cancelButProps">取消</el-button>
        <slot name="centerFooter"></slot>
        <el-button
          v-bind="getProps.confirmButProps"
          :loading="subLoading"
          type="primary"
          @click="handleSubmit"
          >{{ getProps.confirmButText }}
        </el-button>
        <slot name="suffixFooter"></slot>
      </el-space>
    </template>
    <template v-else #footer>
      <slot name="action"></slot>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
  import { getCurrentInstance, ref, unref, computed, useAttrs, provide } from 'vue';
  import { basicProps } from './props'; // 导入基本的props定义
  import { deepMerge } from '@/utils'; // 导入深度合并对象的工具函数
  import { ModalProps, ModalMethods } from './type'; // 导入ModalProps和ModalMethods类型定义
  import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@vicons/antd'; // 导入Ant Design图标组件

  // 使用useAttrs来访问组件的属性
  const attrs = useAttrs();
  // 使用defineProps定义组件的props
  const props = defineProps({ ...basicProps });

  // 使用defineEmits定义组件可以触发的事件
  const emit = defineEmits(['cancel', 'confirm', 'register']);

  // 创建一个响应式引用来存储动态props
  const propsRef = ref(null);

  // 创建响应式变量来控制弹窗显示、子组件加载状态和全屏状态
  const isModal = ref(false);
  const subLoading = ref(false);
  const fullscreen = ref(false);

  // 使用计算属性getProps，返回props和propsRef的合并结果
  const getProps = computed(() => {
    return { ...props, ...(unref(propsRef) as any) };
  });

  // setProps函数，用于异步设置弹窗属性
  async function setProps(modalProps: Partial<ModalProps>): Promise<void> {
    propsRef.value = deepMerge(unref(propsRef) || ({} as any), modalProps);
  }

  // getFullscreen计算属性，返回全屏状态
  const getFullscreen = computed(() => {
    return fullscreen.value;
  });

  // setSubLoading函数，用于设置子组件加载状态
  function setSubLoading(status: boolean) {
    subLoading.value = status;
  }

  // openModal函数，用于打开弹窗
  function openModal() {
    isModal.value = true;
  }

  // handleFullScreen函数，用于切换全屏状态
  function handleFullScreen() {
    fullscreen.value = !fullscreen.value;
  }

  // closeModal函数，用于关闭弹窗并触发close事件
  function closeModal() {
    isModal.value = false;
    subLoading.value = false;
    emit('cancel');
  }

  // onCloseModal函数，用于关闭弹窗并触发close事件
  function onCloseModal() {
    isModal.value = false;
    emit('cancel');
  }

  // handleSubmit函数，用于处理确认操作并触发ok事件
  function handleSubmit() {
    subLoading.value = true;
    emit('confirm');
  }

  // 创建一个ModalMethods类型的对象，包含弹窗的方法
  const modalMethods: ModalMethods = {
    setProps,
    openModal,
    closeModal,
    setSubLoading,
  };

  // 获取当前组件实例，并在实例存在时触发register事件
  const instance = getCurrentInstance();
  if (instance) {
    emit('register', modalMethods);
  }

  // 使用provide函数将handleSubmit、closeModal和subLoading提供给子组件
  provide('handleSubmit', handleSubmit);
  provide('closeModal', closeModal);
  provide('subLoading', subLoading.value);

  // 使用defineExpose将组件的方法和属性暴露给子组件
  defineExpose({
    openModal,
    closeModal,
    setProps,
    setSubLoading,
    handleSubmit,
  });
</script>

<style lang="scss" scoped>
  .dialog-header {
    width: 100%;
    display: flex;
    justify-content: space-around;
    &-title {
      flex: 1;
      font-weight: 400;
      font-size: 16px;
    }
    &-action {
      color: var(--el-color-info);
    }
  }
</style>
